package evan.curtis.pi_player;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

import evan.curtis.pi_player.PiFilesFragment.sshTask;
import evan.curtis.pi_player.util.SSHCommands;

import android.app.AlertDialog;
import android.app.Fragment;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;

public class PandoraFragment extends Fragment {

	private View mContentView;
	private MainActivity mActivity;
	private LinearLayout mLayout;
	private String[] pianobarEvents;
	private Map<String, Integer> stations = new HashMap<String, Integer>();
	private boolean firstPlay = true;
	private Session pianobarCtl;

	private MenuItem playPause;
	private MenuItem next;

	TextView songArtist = null;
	TextView songTitle = null;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		setHasOptionsMenu(true);

		mContentView = inflater.inflate(R.layout.blank_linearlayout, container,
				false);

		// gets the player character from the main activity
		mActivity = (MainActivity) this.getActivity();

		mLayout = (LinearLayout) mContentView.findViewById(R.id.linearlayout);

		setHasOptionsMenu(true);

		// start pianobar control session
		new pianobarCtl().execute();

		startPianobar();

		return mContentView;
	}

	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		super.onCreateOptionsMenu(menu, inflater);
		playPause = menu.add("Play/Pause");
		playPause.setOnMenuItemClickListener(menuItemListener);

		next = menu.add("Next");
		next.setOnMenuItemClickListener(menuItemListener);

	}

	private void startPianobar() {
		// start pianobar
		new sshTask().execute(SSHCommands.START_PIANOBAR);
		Log.i("pianobar", "pianobar started");

		// read pianobar events
		new sshTask().execute(SSHCommands.READ_PIANOBAR_EVENTS);
		Log.i("pianobar", "pianobar events read");

	}

	private void getStations() {
		String pattern = "(station)(\\d+)(=)(.+)";
		Pattern r = Pattern.compile(pattern);
		Matcher m;
		for (String s : pianobarEvents) {
			m = r.matcher(s);
			if (m.find()) {

				// get station number
				int stationNum = Integer.parseInt(m.group(2));
				// get station name
				String stationName = m.group(4);

				stations.put(stationName, stationNum);

			} else {
				
			}

		}

	}

	private String getArtist() {
		String pattern = "(artist=)(.+)";
		Pattern r = Pattern.compile(pattern);
		Matcher m;
		for (String s : pianobarEvents) {
			m = r.matcher(s);
			if (m.find()) {
				if (m.group().length() >= 2) {
					return m.group(2);
				}
			}
		}
		return "";
	}

	private String getSongTitle() {
		String pattern = "(title=)(.+)";
		Pattern r = Pattern.compile(pattern);
		Matcher m;
		for (String s : pianobarEvents) {
			m = r.matcher(s);
			if (m.find()) {
				if (m.group().length() >= 2) {
					return m.group(2);
				}
			}
		}
		return "";
	}

	private void playStation(int num) {
		//kill pianobar and start a new instance, otherwise old station continues to play
		new sshTask().execute("killall pianobar");
		new sshTask().execute(SSHCommands.START_PIANOBAR);
		new sshTask().execute(SSHCommands.CD_PIANOBAR_DIR + "\n" + "echo '"
				+ num + "' " + "> ctl");

		// read song data
		new readSongData().execute();

	}

	private void updateSongData() {
		String artist = getArtist();
		String title = getSongTitle();
		songArtist.setText(artist);
		songTitle.setText(title);
	}

	private void inflateLayout() {

		// int stationNum = 0;
		// int color = getResources().getColor(R.color.text_view_color);
		// int alternateColor = getResources().getColor(
		// R.color.text_view_alternate);

		Spinner spinner = new Spinner(mActivity);
		mLayout.addView(spinner);

		// stores station names
		List<String> list = new ArrayList<String>();
		//list.add("Select Station");
		
		Iterator it = stations.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry pairs = (Map.Entry) it.next();
			String stationName = (String) pairs.getKey();
			list.add(stationName);
		}

		ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(mActivity,
				android.R.layout.simple_spinner_item, list);
		dataAdapter
				.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		spinner.setAdapter(dataAdapter);
		spinner.setOnItemSelectedListener(stationOnClickListener);

		songArtist = new TextView(mActivity);
		songTitle = new TextView(mActivity);
		mLayout.addView(songArtist);
		mLayout.addView(songTitle);

	}

	private OnItemSelectedListener stationOnClickListener = new OnItemSelectedListener() {

		@Override
		public void onItemSelected(AdapterView<?> parent, View view, int pos,
				long id) {
			String stationName = parent.getItemAtPosition(pos).toString();
			int stationNum = stations.get(stationName);
			playStation(stationNum);

		}

		@Override
		public void onNothingSelected(AdapterView<?> arg0) {
			// TODO Auto-generated method stub

		}
	};

	public class readSongData extends AsyncTask<String, Integer, String> {

		@Override
		protected String doInBackground(String... params) {
			String result = null;

			try {
				Thread.sleep(5000);
				result = mActivity.sshCommand(SSHCommands.READ_PIANOBAR_EVENTS);
			} catch (JSchException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			return result;
		}

		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			pianobarEvents = result.split("\n");
			updateSongData();
		}
	}

	// The definition of our task class
	public class sshTask extends AsyncTask<String, Integer, String> {

		String command = "";
		ProgressBar pBar;
		AlertDialog dialog = null;

		@Override
		protected void onPreExecute() {
			super.onPreExecute();

			// show wait dialog
			Context c = mActivity;
			dialog = new AlertDialog.Builder(c).create();
			dialog.setTitle("Wait.");
			LinearLayout linear = new LinearLayout(c);
			linear.setOrientation(LinearLayout.VERTICAL);
			dialog.setView(linear);
			LayoutInflater inflater = (LayoutInflater) c
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

			View volumeView = inflater.inflate(R.layout.wait_dialog, linear);
			pBar = (ProgressBar) volumeView.findViewById(R.id.progressBar);
			dialog.show();

		}

		@Override
		protected String doInBackground(String... params) {

			String task = params[0];
			command = task;
			String s = "";
			try {
				if (command.equals(SSHCommands.START_PIANOBAR)) {
					s = mActivity.sshCommand(task);
				} else {
					s = pianobarCommand(task);
				}

			} catch (JSchException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				Log.i("iofail", "fail");
				e.printStackTrace();
			}

			return s;
		}

		@Override
		protected void onProgressUpdate(Integer... progress) {
			super.onProgressUpdate(progress);
			pBar.setProgress(progress[0]);
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);

			dialog.cancel();

			if (command.equals(SSHCommands.READ_PIANOBAR_EVENTS)) {
				Log.i("pbar_events", result);
				pianobarEvents = result.split("\n");

				getStations();
				inflateLayout();

			}

		}

	}

	public class pianobarCtl extends AsyncTask<String, Integer, String> {

		@Override
		protected String doInBackground(String... arg0) {
			String host = "192.168.1.4";
			String user = "pi";
			String pwd = "Kg7$m4";
			int port = 22;

			java.util.Properties config = new java.util.Properties();
			config.put("StrictHostKeyChecking", "no");
			JSch jsch = new JSch();
			try {
				pianobarCtl = jsch.getSession(user, host, port);
			} catch (JSchException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			pianobarCtl.setPassword(pwd);
			pianobarCtl.setConfig(config);
			try {
				pianobarCtl.connect();
			} catch (JSchException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Log.i("sshConnect", "Connected");
			return null;
		}

	}

	public String pianobarCommand(String command) throws JSchException,
			IOException {

		String result = "";

		Channel channel = pianobarCtl.openChannel("exec");
		((ChannelExec) channel).setCommand(command);
		channel.setInputStream(null);
		((ChannelExec) channel).setErrStream(System.err);
		InputStream in = channel.getInputStream();

		channel.connect();

		byte[] tmp = new byte[1024];

		while (true) {
			while (in.available() > 0) {
				int i = in.read(tmp, 0, 1024);
				if (i < 0)
					break;
				result += new String(tmp, 0, i);
			}
			if (channel.isClosed()) {
				Log.i("exit-status: ",
						Integer.toString(channel.getExitStatus()));
				break;
			}
			try {
				Thread.sleep(1000);
			} catch (Exception ee) {
			}

		}

		channel.disconnect();

		return result;

	}

	private OnMenuItemClickListener menuItemListener = new OnMenuItemClickListener() {

		public boolean onMenuItemClick(MenuItem m) {
			if (m.getTitle().equals("Next")) {
				new sshTask().execute(SSHCommands.PBAR_NEXT_SONG);
				// read song data
				new readSongData().execute();
			} else if (m.getTitle().equals("Play/Pause")) {
				new sshTask().execute(SSHCommands.PBAR_PLAY_PAUSE);
			}
			return false;

		}
	};

}
